XNA Game Studio Tutorial
Adok/Hugi
Introduction
XNA Game Studio 2.0 is Microsoft's new framework for game development, targeted primarily at students and hobbyists. With it you can develop games for the .NET 2.0 platform and for the Xbox 360 using C#, a new language based on C++ which is very easy to learn if you already know C++. I've come to the conclusion that it's a nice framework as it handles many chores and allows you to focus on the gameplay. In this tutorial I'll show you how to implement a simple 2D game with it.
Requirements
You need Visual Studio 2005. The following versions of it are supported by XNA Game Studio 2.0:
Visual C# 2005 Express Edition
Visual Studio 2005 Standard Edition
Visual Studio 2005 Professional Edition
Visual Studio 2005 Tools for the Microsoft Office System
Visual Studio 2005 Team Edition for Software Architects
Visual Studio 2005 Team Edition for Software Developers
Visual Studio 2005 Team Edition for Software Testers
Visual Studio 2005 Team Edition for Database Professionals
Visual Studio 2005 Team Suite
The first one is free, so you might consider downloading it unless you already have any of the other editions. It's available from microsoft.com. Older versions of Visual Studio 2005 Professional Edition need to be updated with Service Pack 1, which is available from microsoft.com as well.
You can then download and install XNA Game Studio 2.0 from microsoft.com.
The players of your game will need the .NET Framework 2.0 Redistributable and the XNA Framework Redistributable, both of which are available at microsoft.com. The exact download URLs are [1] and [2], respectively. Don't forget to include these URLs in the readme file of your game.
Game Skeleton
When you start Visual Studio and create a new Windows project with XNA Game Studio, you get a file called Game1.cs. This is your main code file. As the line
public class Game1 : Microsoft.Xna.Framework.Game
shows, it's a subclass of Microsoft.Xna.Framework.Game. This class has a method called Run, which is executed by the actual program class, Program.cs. Run first calls Initialize, then LoadContent, and after that it enters the main loop: By default, every once in a given time interval, Update is called, followed by Draw. So what you have to do basically is clear: initialize variables in Initialize, load the graphics and other contents in LoadContent (or do it in Initialize and ignore LoadContent - that's also possible), update variables and process the players' inputs in Update, and display everything on screen in Draw.
The following paragraph is about some details on the main loop, skip it if you just want to get a quick introduction to XNA Game Studio.
Details on the main loop
By default, Update is called every time a time interval specified by TargetElapsedTime is elapsed. TargetElapsedTime is an object of the class TimeSpan and is by default 00:00:00.166667, i.e. 1/60th of a second. This is a good choice for a screen refresh rate of 60 Hz - mind that Draw is also called 60 times per second. If you want, you can change TargetElapsedTime. You can even abolish the waiting for an elapsed time by setting Game.IsFixedTimeStep to false. Then, however, you have to do the synchronization yourself, which will make coding more difficult.
If the game is running slowly so that the Update method cannot be called as often as specified by TargetElapsedTime, the variable IsRunningSlowly is set to true. If you create a more sophisticated game you might want to check for this variable and include frame skipping.
Content
In the project map explorer, there's a folder named Content. If you right-click it, you can add graphics, sounds, fonts, and other content to it. That's the way to include data in your game. Loading the data in the code is a piece of cake. For example, a 2D texture is loaded with the following command:
texture = this.Content.Load
Note that you have to write the filename without the extension! Your files are automatically converted from whatever format they are originally in - .bmp, .png etc. - to an internal format of XNA. Thus they get a different extension, and that's why the Load method has been created in such a way that extensions are obsolete.
Window size and full screen
By default, the game is a windowed application in a window of 800x600 pixels which cannot be resized. If you want it to be resizeable, you must write:
this.Window.AllowUserResizing = true;
If you want to use full screen, you must write something like:
this.graphics.PreferredBackBufferWidth = 1024;
this.graphics.PreferredBackBufferHeight = 768;
this.graphics.IsFullScreen = true;
Displaying sprites
For graphics output, there's one important object that is defined in Game1.cs:
SpriteBatch spriteBatch;
If you want to draw graphics, you must begin a new SpriteBatch, and when you're done, you must end this SpriteBatch. That means your Draw method will most likely look like this:
spriteBatch.Begin();
// here comes the code for drawing the objects
spriteBatch.End();
To draw a sprite stored as a 2D texture, you use a command like the following:
spriteBatch.Draw(texture, new Vector2(position_x, position_y), Color.White);
The position is given in pixels. Color.White means that the texture will be displayed with original colours. If you want to create a fading effect, you can write Color(255, 255, 255, opacity) and have the variable opacity run from e.g. 0 to 255 (maximum).
Areas inside the texture which are purple (that is Color(255, 0, 255)) are not displayed. In this way you achieve transparency.
There are other variants of the Draw method with more parameters, allowing e.g. scaling and rotating of your texture. Simply check out what's possible by inserting a "," after Color.White in the previous line inside Visual Studio.
Displaying text
For displaying text, you can use the DrawString method of a SpriteBatch object. The first parameter is a SpriteFont object so you must first create one, and you must also load the SpriteFont by means of a code line like:
Font1 = this.Content.Load
A SpriteFont is based on a true-type font with a given size and shape (regular, bold, italic). You can create a new SpriteFont simply by right-clicking the Content folder in the project map, selecting "Add New Element" and then "Sprite Font". The rest is done interactively.
Basically, the parameters of DrawString are the font, the string, the position on screen and the colour, but there are also some variants which allow e.g. scaling and font effects.
Input
Keyboard input is obtained by a code line like:
KeyboardState keyboardState = Keyboard.GetState();
To check whether Space has been pressed, write:
if (keyboardState.IsKeyDown(Keys.Space))
And so on.
The mouse state is polled with:
MouseState mouseState = Mouse.GetState();
After that line, mouseState.X and mouseState.Y contain the X and Y coordinates of the mouse pointer respectively. To check whether the left mouse button is being pressed, write:
if (mouseState.LeftButton == ButtonState.Pressed)
The code for the right and middle buttons is analogous.
Summary
With this, we already know enough to code a 2D game. I've included the source code of a simple one-player Tetris-like game in the bonus pack (adoktris_1player.zip). I guess it's easy to understand. If you have any questions about it, feel free to ask me.
In order to learn more about XNA Game Studio (audio, 3D, file operations, networking etc.), check out MSDN.
Adok/Hugi